package cn.xinfei.xdecision.data.core.frame.executors.collect.handler;

import cn.xinfei.xdecision.common.model.datax.enums.CollectStageEnum;
import cn.xinfei.xdecision.common.service.datax.datainterface.v2.VarInterfaceInfoService;
import cn.xinfei.xdecision.data.core.cache.VarInterfaceCache;
import cn.xinfei.xdecision.data.core.frame.executors.VarContext;
import cn.xinfei.xdecision.data.core.frame.executors.collect.VarHandler;
import cn.xinfei.xdecision.data.core.vo.VarCollectAwareVO;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class VarApiAndVariablesHandler implements VarHandler<VarCollectAwareVO> {

    @Autowired
    VarInterfaceInfoService varInterfaceInfoService;

    @Autowired
    VarInterfaceCache varInterfaceCache;

    @Override
    public void doHandle(VarContext<VarCollectAwareVO> context) {
        VarCollectAwareVO collectRequestVO = context.get();
        Set<String> varCodes = collectRequestVO.getVarCodes();
        String requestId = collectRequestVO.getRequestId();
        collectRequestVO.setCollectStageEnum(CollectStageEnum.REAL_TIME_COLLECT);

        List<String> allVars = Lists.newArrayList();
        Map<String, List<String>> allApiAndVarsMap;
        Optional<Map<String, List<String>>> apiAndVarCodesRelMetaDataCache = Optional.ofNullable(
                varInterfaceCache.loadApiAndVarCodesRelMetaData());

        if (apiAndVarCodesRelMetaDataCache.isPresent()) {
            log.info("requestId = {} VarApiAndVariablesHandler 查询缓存 ApiAndVarCodesRelMetaData", requestId);
            allApiAndVarsMap = apiAndVarCodesRelMetaDataCache.get().entrySet()
                    .stream().filter(var ->
                            CollectionUtils.isNotEmpty(
                                    CollectionUtils.intersection(varCodes, new HashSet<>(var.getValue()))
                            )
                    )
                    .collect(Collectors.toMap(Map.Entry::getKey,
                            item -> item.getValue()
                                    .stream()
                                    .filter(varCodes::contains)
                                    .filter(Objects::nonNull)
                                    .collect(Collectors.toList()))
                    );
        } else {
            allApiAndVarsMap = varInterfaceInfoService.selectAllApiAndVarsByVarCodes(varCodes);
        }

        if (MapUtils.isEmpty(allApiAndVarsMap)) {
            log.info("requestId = {} allApiAndVarsMap is empty!", requestId);
        } else {
            allVars = allApiAndVarsMap
                    .values().stream().flatMap(Collection::stream)
                    .filter(varCodes::contains)
                    .distinct()
                    .collect(Collectors.toList());
        }

        log.info("requestId = {}, allApiAndVarsMap: {}", requestId, JSONObject.toJSONString(allApiAndVarsMap));
        collectRequestVO.setChargedCodes(allVars);
        collectRequestVO.setApiVariablesMap(allApiAndVarsMap);
        context.setContext(collectRequestVO);
    }
}
